/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef X509_CERT_SELECTOR_H
#define X509_CERT_SELECTOR_H

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "cf_blob.h"
#include "cf_object_base.h"
#include "cf_result.h"
#include "x509_certificate.h"

typedef struct HcfX509CertSelector HcfX509CertSelector;

// todo: js enum
typedef enum
{
    GENERAL_NAME_TYPE_OTHER_NAME = 0,
    GENERAL_NAME_TYPE_RFC822_NAME = 1,
    GENERAL_NAME_TYPE_DNS_NAME = 2,
    GENERAL_NAME_TYPE_X400_ADDRESS = 3,
    GENERAL_NAME_TYPE_DIRECTORY_NAME = 4,
    GENERAL_NAME_TYPE_EDI_PARTY_NAME = 5,
    GENERAL_NAME_TYPE_UNIFORM_RESOURCE_ID = 6,
    GENERAL_NAME_TYPE_IP_ADDRESS = 7,
    GENERAL_NAME_TYPE_REGISTERED_ID = 8,
} CfGeneralNameType;

typedef struct
{
    CfGeneralNameType type;
    CfBlobArray blobArr; // Array<Uint8Array>
} SubjectAlternaiveNameData;

typedef struct
{
    SubjectAlternaiveNameData *data;
    uint32_t count;
} SubjectAlternaiveNameDataBlob;

typedef struct NapiX509Certificate NapiX509Certificate;
typedef struct
{
    SubjectAlternaiveNameDataBlob *subjectAlternativeNames;
    bool matchAllSubjectAltNames;
    CfBlob authorityKeyIdentifier; // Uint8Array
    int32_t minPathLenConstraint;  // number
    NapiX509Certificate *x509Cert;
    CfBlob validDate;             // string
    CfBlob issuer;                // Uint8Array
    CfBlobArray extendedKeyUsage; // Array<string>
    CfBlob keyUsage;              // Array<boolean>
    CfBlob nameConstraint;        // Uint8Array
    CfBlobArray certPolicy;       // Array<string>
    CfBlob privateKeyValid;       // string
    CfBlob serialNumber;          // big int
    CfBlob subject;               // Uint8Array
    CfBlob subjectKeyIdentifier;  // Uint8Array
    CfBlob publicKey;             // DataBlob
    CfBlob publicKeyAlgID;        // string
} HcfX509CertSelectorData;

struct HcfX509CertSelector
{
    struct CfObjectBase base;
    HcfX509CertSelectorData *data;
};

#ifdef __cplusplus
extern "C"
{
#endif

    /**
     * @brief Generate X509 cert selector instance.
     */
    CfResult HcfX509CertSelectorCreate(HcfX509CertSelector **pathValidator);

    /**
     * @brief Add data to HcfX509CertSelectorData::SubjectAlternativeNames,
     * @param [name] - RfC822 encoding.
     */
    CfResult AddSubjectAlternativeNames(HcfX509CertSelector *self, int32_t type, CfBlob name);

    /**
     * @brief Add data to HcfX509CertSelectorData::SubjectAlternativeNames,
     * @param [cert] - X509Cert innert Object .
     */
    CfResult match(HcfX509CertSelector *self, HcfX509Certificate *cert, bool *boolRet);

#ifdef __cplusplus
}
#endif

#endif // X509_CERT_SELECTOR_H
